package com.blx.utils.annotation;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;

@Component
@Aspect
public class ValidateAspectHandle {

	/**
	 * 
	 */
	@SuppressWarnings("finally")
	@Around("@annotation(com.blx.utils.annotation.ValidateGroup)")
	public Object  validateAround(ProceedingJoinPoint joinPoint) throws Throwable{
		boolean flag = false;
		ValidateGroup vg = null;
		Object[] args = null;
		Method method = null;
		Object target = null;
		String methodName = null;
		try {
			methodName = joinPoint.getSignature().getName();
			target = joinPoint.getTarget();
			method = getMethodByClassAndName(target.getClass(),methodName);
			args = joinPoint.getArgs();
			vg = (ValidateGroup) getAnnotationByMethod(method,ValidateGroup.class);
//			flag = validateField(vg.fields(),args);
		} catch (Throwable t) {
			flag = false;
		}finally{
			if(flag){
				System.out.println("验证通过");
				return joinPoint.proceed();
			}else{
				System.out.println("验证失败");
				Class returnType = method.getReturnType();
				if(returnType == String.class){
					return "/404";
				}else if (returnType == ModelAndView.class){
					return new ModelAndView("/404");
				}else{
					return null;
				}
			}
		}
				
	}
	/**
	 * @Description: 验证参数是否合法
	 */
	private boolean validateField(ValidateField[] fields, Object[] args) throws Exception{
		for(ValidateField validateField : fields){
			Object arg = null;
			if("".equals(validateField.filedName())){
				arg = args[validateField.index()];
			}else{
				arg = getFieldByObjectAndFileName(args[validateField.index()],validateField.filedName());
			}
			if(validateField.notNull()){
				if(arg == null){
					return false;
				}
			}else{
				if(arg == null){
					return true;
				}
			}
			if(validateField.maxLen() > 0){
				if(((String)arg).length() > validateField.maxLen()){
					return false;
				}
			}
			if(validateField.minLen() > 0){
				if(((String)arg).length() < validateField.minLen()){
					return false;
				}
			}
			if(validateField.maxVal() != -1){
				if((Integer)arg < validateField.minVal()){
					return false;
				}else{
					return false;
				}
			}
		}
		return true;
	}
	/**
	 * 根据对象和属性名得到属性
	 */
	private Object getFieldByObjectAndFileName(Object targetObj, String filedName) throws Exception{
		String tmp[] = filedName.split("\\.");
		Object arg = targetObj;
		for (int i = 0; i < tmp.length; i++) {
			Method method = arg.getClass().getMethod(getGetterNameByFiledName(tmp[i]));
			arg = method.invoke(arg);
		}
		return null;
	}
	/**
	 * 根据属性名 得到属性的getter方法
	 */
	private String getGetterNameByFiledName(String fieldName) {
		return "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
	}
	/**
	 * 
	* @Description: 根据目标方法和注解类型，或者该目标方法的指定注解
	 */
	private Annotation getAnnotationByMethod(Method method,Class annoClass) {
		Annotation all[] = method.getAnnotations();
		for (Annotation annotation : all) {
			if(annotation.annotationType() == annoClass){
				return annotation;
			}
		}
		return null;
	}
	/**
	 * 根据类和方法名获取方法
	 */
	private Method getMethodByClassAndName(Class c,String methodName) {
		Method[] methods = c.getDeclaredMethods();
		for (Method method : methods) {
			if(method.getName().equals(methodName)){
				return method;
			}
		}
		return null;
	}
}
